/*
 * Created by Jaren at 2021/10/28 17:43
 */
import 'package:ble_plugin/ble_device_filter.dart';
import 'package:ble_plugin/ble_plugin.dart';
import 'package:ble_plugin/ble_uuid.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:jieli_ble_ota_plugin_example/base/base.dart';
import 'package:jieli_ble_ota_plugin_example/global/global.dart';
import 'package:jieli_ble_ota_plugin_example/ota/fm_update_view.dart';
import 'package:jieli_ble_ota_plugin_example/ota/fw_update_controller.dart';
import 'package:jieli_ble_ota_plugin_example/widget/prompt.dart';

class SearchController extends BaseController {
  static final _bleUuid1 =
      BleUuid("0000ffe5-0000-1000-8000-00805f9b34fb", "0000ffe9-0000-1000-8000-00805f9b34fb", "0000ffe0-0000-1000-8000-00805f9b34fb", "0000ffe4-0000-1000-8000-00805f9b34fb");
  static final _bleUuid2 =
      BleUuid("0000ae00-0000-1000-8000-00805f9b34fb", "0000ae01-0000-1000-8000-00805f9b34fb", "0000ae00-0000-1000-8000-00805f9b34fb", "0000ae02-0000-1000-8000-00805f9b34fb");
//    static final _bleUuid3 = BleUuid('', '', '', '');

  // 扫描到的设备列表
  final devices = <BluetoothDevice>[].obs;

  // 当前系统蓝牙状态
  Rx<BluetoothState> btState = BluetoothState.unknown.obs;

  final BleManager _bleManager = BleManager();

  RxBool searching = false.obs;
  RxBool connecting = false.obs;

  @override
  init() {
    _bleManager.getBtState().then((value) => btState.value = value);
    _bleManager.addSupportedBleServices([
      _bleUuid1,
      _bleUuid2, /*_bleUuid3*/
    ]);
    _bleManager.onStateChangedCallback = _onBtDeviceStateChangedCallback;
  }

  bool scan() {
    if (btState.value != BluetoothState.on) {
      print("btState.value: ${btState.value}");
      // return false;
    }
    if (searching.value) stopScanning();

    _bleManager.scan(filter: BleDeviceNameFilter("^.+-[0-9A-F]{8}\$")).listen((scanResult) {
      devices.add(scanResult.device);
    }, onDone: () => searching.value = false);

    searching.value = true;
    return true;
  }

  bool stopScanning() {
//        if (btState.value != BluetoothState.on) {
//            return false;
//        }
    _bleManager.stopScan();
    searching.value = false;
    return true;
  }

  connect({BluetoothDevice? device, String? identify, String? name}) {
    if (searching.value) stopScanning();
    // _bleManager.connect(device: device, name: name, timeout: const Duration(seconds: 10));
    _bleManager.connect(
        device: device,
        id: identify,
        // name: name,
        timeout: const Duration(seconds: 10),
        timeoutCallback: () {
          connecting.value = false;
          isLoading.value = false;
          Prompt.showToast('Connect timeout');

          print('Connect timeout');
        });
    isLoading.value = true;
  }

  _onBtDeviceStateChangedCallback(BluetoothDevice device, state, {String? flag}) async{
    print(state);

    var fwUpdating = Global.getInstance().get("fw_updating", false);
    var connectedCallback = Global.getInstance().get("bt_state_change_handler");

    switch (state) {
      case BluetoothDeviceState.disconnected:
        if (fwUpdating) {
          if (connectedCallback != null) connectedCallback(false, device.name);
          return;
        }
        connecting.value = false;
        isLoading.value = false;
        Prompt.showToast('Device has disconnected');

        print('Device has disconnected');
        break;
      case BluetoothDeviceState.connecting:
        print('Device is connecting');
        break;
      case BluetoothDeviceState.connected:
        print('Device has connected');
        BleManager().config({'writeWithoutResponse': true, 'mtu': 182});
        if (fwUpdating) {
          // BleManager().config(InMotionProtocol.getDeviceConfig(device.name));
          await _bleManager.requestMtu(220, device: device);
          if (connectedCallback != null) connectedCallback(true, device.name);
          return;
        }
        connecting.value = false;
        isLoading.value = false;
        Prompt.showToast('Device has connected');
        await _bleManager.requestMtu(220, device: device);
        Get.to(FwUpdatePage(), binding: BindingsBuilder(() {
          Get.put(FwUpdateController());
        }));
        break;
      case BluetoothDeviceState.disconnecting:
        print('Device is disconnecting');
        break;
    }
  }
}
